using UnityEngine;
using System.Collections;

public class CameraControl : MonoBehaviour
{
    #region Attributes

    public Camera mainCamera = null;
    public Vector3 distance = Vector3.zero;
    
    public float yOffset = 0.0f;
    public float acceleration = 0.0f;
    public float slowdown = 0.0f;
    public float minSpeed = 0.0f;
    public float maxSpeed = 0.0f;
    
    private float speed = 0.0f;
    private bool isMovingInYAxis = false;
    private Vector3 targetDistance;

    #endregion

    #region Methods

    private Vector3 CalculateMoveDistance(Vector3 currentTargetDistance)
    {
        Vector3 moveDistance = currentTargetDistance - this.mainCamera.transform.position;

        /* Calculate move in Y */
        if (!this.isMovingInYAxis && this.yOffset < moveDistance.y)
            this.isMovingInYAxis = true;
        else if (this.isMovingInYAxis && moveDistance.y < 0.5)
            this.isMovingInYAxis = false;

        if (!this.isMovingInYAxis)
            moveDistance.y = 0;

        return moveDistance;
    }

    private void Move(Vector3 moveDistance, Vector3 currentTargetDistance)
    {
        if (moveDistance.magnitude > 0.5f) /* if not hit Target */
        {
            moveDistance.Normalize(); // Transform in direction
            if (targetDistance == currentTargetDistance) /* Target doesn't move */
                moveDistance = PhysxHelper.GetUniformAccelerationRectilinearMotion(moveDistance, ref this.speed, -this.slowdown);
            else if (this.speed < this.maxSpeed) /* Target moves */
                moveDistance = PhysxHelper.GetUniformAccelerationRectilinearMotion(moveDistance, ref this.speed, this.acceleration);
            else /* Camera moves at MaxSpeed */
                moveDistance = PhysxHelper.GetUniformRectilinearMotion(moveDistance, this.speed);

            this.mainCamera.transform.Translate(moveDistance);
        }
        else /* Reset Speed */
            this.speed = this.minSpeed;
    }

    #endregion

    #region Unity Methods

    void Start()
    {
        if (this.mainCamera == null)
            this.mainCamera = Camera.main;

        this.mainCamera.transform.position = this.transform.position + this.distance;
        this.mainCamera.transform.LookAt(this.transform.position);
    }

	void LateUpdate() 
    {
        Vector3 currentTargetDistance = this.transform.position + this.distance;
        Vector3 moveDistance = this.CalculateMoveDistance(currentTargetDistance);
        this.Move(moveDistance, currentTargetDistance);
        
        // Final Tasks
        this.speed = Mathf.Min(this.speed, this.maxSpeed);
        this.speed = Mathf.Max(this.speed, this.minSpeed);
        this.targetDistance = currentTargetDistance;
    }

    #endregion
}
